package com.lyfei.yd.system.service;

import com.alibaba.fastjson2.JSON;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.lyfei.yd.common.exception.CustomException;
import com.lyfei.yd.system.domain.dto.PageQueryDto;
import com.lyfei.yd.system.domain.dto.SpecKeyDto;
import com.lyfei.yd.system.domain.entity.*;
import com.lyfei.yd.system.domain.vo.SpecKeyAndItemsVo;
import com.lyfei.yd.system.mapper.SpecKeyMapper;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;

@Service("specKeyService")
public class SpecKeyService extends BaseService<SpecKeyMapper, SpecKey> {

    @Autowired
    private SkuSpecService skuSpecService;

    @Autowired
    private SpecValueService specValueService;

    @Autowired
    private SpuSpecKeyService spuSpecKeyService;

    @Autowired
    private SkuService skuService;

    public void create(SpecKeyDto specKeyDto) {
        if(this.getByName(specKeyDto.getName())!= null){
            throw new CustomException("规格名称已存在");
        }


        SpecKey specKey = new SpecKey();
        BeanUtils.copyProperties(specKeyDto, specKey);
        specKey.setCreateTime(new Date());
        specKey.setUpdateTime(new Date());
        this.save(specKey);
    }

    @Transactional
    public void update(SpecKeyDto specKeyDto, Long id) {
        SpecKey specKey = this.getById(id);
        if(specKey == null){
            throw new CustomException("规格不存在");
        }

        BeanUtils.copyProperties(specKeyDto, specKey);
        specKey.setUpdateTime(new Date());
        this.updateById(specKey);

        // 更新Sku的specs字段
        List<SkuSpec> skuSpecs = skuSpecService.list(new LambdaQueryWrapper<SkuSpec>().eq(SkuSpec::getKeyId, id));
        if(skuSpecs.isEmpty()) {
            return;
        }

        List<Long> skuIds = skuSpecs.stream().map(SkuSpec::getSkuId).collect(Collectors.toList());
        skuIds.forEach(skuId ->{
            Sku sku = skuService.getById(skuId);
            List<SkuSpec> tempSkuSpecs = skuSpecs
                    .stream()
                    .filter(skuSpec -> skuSpec.getSkuId().equals(skuId))
                    .collect(Collectors.toList());

            ArrayList<SpecKeyValue> specs = new ArrayList<>();
            tempSkuSpecs.forEach(skuSpec -> {
                SpecKeyValue specKeyValue = specValueService.getSpecKeyValue(skuSpec.getKeyId(), skuSpec.getValueId());
                specs.add(specKeyValue);
            });
            sku.setSpecs(JSON.toJSONString(specs));
            skuService.updateById(sku);
        });
    }

    @Transactional
    public void delete(Long id) {
        SpecKey specKey = this.getById(id);
        if(specKey == null) {
            throw new CustomException("规格不存在");
        }

        this.removeById(id);

        // 删除规格对应的规格值
        specValueService.remove(new LambdaQueryWrapper<SpecValue>().eq(SpecValue::getSpecId, id));
    }

    public IPage<SpecKey> listPage(PageQueryDto dto) {
        return this.page(new Page<>(dto.getCurrent(), dto.getPageSize()));
    }

    public SpecKey getByName(String name) {
        return this.getOne(new LambdaQueryWrapper<SpecKey>().eq(SpecKey::getName, name)
                .eq(SpecKey::getDeleted, 0));
    }

    public SpecKeyAndItemsVo getSpecKeyAndItems(Long id) {
        SpecKey specKey = this.getById(id);
        if(specKey == null) {
            throw new CustomException("规格不存在");
        }

        List<SpecValue> specValues = specValueService.list(new LambdaQueryWrapper<SpecValue>().eq(SpecValue::getSpecId, id));
        return new SpecKeyAndItemsVo(specKey, specValues);
    }

    public List<SpecKey> getBySpuId(Long spuId) {
        List<SpuSpecKey> spuSpecKeys = spuSpecKeyService.list(
                new LambdaQueryWrapper<SpuSpecKey>().eq(SpuSpecKey::getSpuId, spuId));

        List<SpecKey> specKeys = new ArrayList<>();
        for (SpuSpecKey spuSpecKey : spuSpecKeys) {
            SpecKey specKey = this.getById(spuSpecKey.getSpecKeyId());
            specKeys.add(specKey);
        }

        return specKeys;
    }
}
